package core.gamemodes;

import java.awt.Color;
import java.awt.Point;
import java.util.Iterator;
import java.util.Vector;

import ai.WorldAI;

import core.*;
import core.actions.AddMachinegun;
import core.actions.FireLaser;
import core.actions.FireMissile;
import core.actions.FireMortar;
import core.actions.FireShotgun;
import core.actions.FireSniper;
import core.actions.MoveHero;
import core.actions.NextUnit;
import core.mountedWeapons.GenericPistol;
import core.mountedWeapons.MountedWeapon;
import core.units.ArtilleryBuggy;
import core.units.HeroUnit;
import core.units.Seeker;
import core.units.Unit;

public class Survival extends GameMode{
	
	
	private Vector<Unit> currentTargets=new Vector<Unit>();
	private int phase = 1;
	private int enemyStrength = 1;
	private boolean messagesOn = true;

	
	public Survival(SingleButtonGame m){
		super(m);
		name = "Survival";
		forcedMap = "survival.txt";
	}
	public void setupPlayerData(PlayerData d){
		setupUnits(d);
			
	}
	
	private void setupUnits(PlayerData d){
		Unit u = new HeroUnit(0, 0, null);
		u.setSpriteName("testTankV1.png");
		u.addWeapon(new GenericPistol(10, 70));
		u.actionMap.clear();
		u.actionMap.setWantedDepth(2);
					
		u.actionMap.add(new MoveHero());
		u.actionMap.add(new NextUnit());
		
		u.actionMap.add(new FireMortar());
		u.actionMap.add(new FireLaser());
		
		u.actionMap.add(new FireShotgun());		
		u.actionMap.add(new FireSniper());
		
		u.actionMap.add(new FireMissile());
		u.actionMap.add(new AddMachinegun());
		
		u.actionMap.set(new FireMissile(), 0, 2);
		
		
		
		d.addUnit(u);
		d.selectNextUnit();
		
		
		u = new HeroUnit(0, 0, null);
		u.setImageName("iconLightTank1.png");
		u.setSpriteName("testTankV1.png");
		u.setSpeed(600);		
		u.addWeapon(new GenericPistol(20, 150));
		u.actionMap.clear();
		u.actionMap.setWantedDepth(2);
		
		u.actionMap.add(new MoveHero());
		u.actionMap.add(new NextUnit());
		
		u.actionMap.add(new FireShotgun());	
		u.actionMap.add(new FireSniper());
		
		u.actionMap.set(new FireMissile(), 0, 2);
		
		
		d.addUnit(u);
			
	}
	
	protected void additionalPlayerSetup(Player p){
		p.team=1;
		for(Unit u : p.getPlayerData().getUnits()){
			
			
			//u.linkActions();

		}
		p.spawnAdditionalUnit();
	}
	public void initConfiguration(){
	}
	public void initGame(){
		MessageHandler.showMessage("Welcome to Survival. Don't worry about taking a few hits, at the end of each wave all units are revived =D", "iconInfo.png");
		enemyStrength=playerCounter+2;
		
		for(Point p : main.map.getPoints("target"+phase)){
			
			spawnEnemy(p, 0);
			
		}
		phaseMessage();
	}
	public void onFrameLogic(){
		boolean allDead=true;
		Iterator<Unit> it = currentTargets.iterator();
		while(it.hasNext() && allDead){
			if(it.next().isAlive())
				allDead=false;
		}
		if(allDead){
			currentTargets.clear();
			phase++;
			if(main.map.getPoints("target"+phase).isEmpty()){
				phase=1;
				enemyStrength = enemyStrength+playerCounter;
			}
			int unitCounter = 0;
			for(Point p : main.map.getPoints("target"+phase)){
				if(main.map.getPoints("target"+phase).size() == 1){ //boss
					spawnEnemy(p, 2);
				}
				else{				
					switch(phase){
					case 1:
						spawnEnemy(p, 0);
						break;
					case 2:
						if(unitCounter % 4 == 0)
							spawnEnemy(p, 1);
						else
							spawnEnemy(p, 0);
						break;
					case 3:
						if(unitCounter % 4 != 0)
							spawnEnemy(p, 1);
						else
							spawnEnemy(p, 0);
						break;
					case 4:
						if(unitCounter % 2 == 0)
							spawnEnemy(p, 0);
						else
							spawnEnemy(p, 3);
						break;
					default:
						spawnEnemy(p, 0);
						break;
					}
				}
				
				
				unitCounter++;
			}
			phaseMessage();
			
			for(Player p : main.getPlayers()){
				p.setAlive(true);
				for(Unit u : p.getPlayerData().getUnits()){
					if(u.isDead()){
						u.spawn(p.getSpawnPoint());
					}
				}
			}
		}
	}
	
	private void spawnEnemy(Point p, int type){
		Unit newUnit;
		MountedWeapon weapon;
		switch(type){
		case 1: // Skirmisher
			newUnit = new ArtilleryBuggy(CustomUtil.pointOffset(p, 50), AI);
			newUnit.setImageName("iconLightTank1.png");
			newUnit.setWidth(25000);
			newUnit.setHeight(20000);
			newUnit.setMaxHealth(50*enemyStrength);
			newUnit.setSpeed(50*enemyStrength);
			weapon = new GenericPistol(5*enemyStrength, 500);
			weapon.setRange(600000);
			newUnit.addWeapon(weapon);
			currentTargets.add(newUnit);
			main.units.add(newUnit);
			newUnit.spawn(p);
			break;
		case 2: // Boss
			newUnit = new Seeker(CustomUtil.pointOffset(p, 50), AI);
			newUnit.setImageName("iconTank1.png");
			newUnit.setWidth(50000);
			newUnit.setHeight(40000);
			newUnit.setMaxHealth(enemyStrength*500);
			newUnit.setSpeed(50+7*enemyStrength);
			weapon = new GenericPistol(100, 70);
			weapon.setRange(120000+2000*enemyStrength);
			newUnit.addWeapon(weapon);
			currentTargets.add(newUnit);
			main.units.add(newUnit);
			newUnit.spawn(p);
			break;
		case 3: // Small
			newUnit = new Seeker(CustomUtil.pointOffset(p, 50), AI);
			newUnit.setImageName("iconTank1.png");
			newUnit.setSpriteName("arrowSprite.png");
			newUnit.setWidth(15000);
			newUnit.setHeight(10000);
			newUnit.setMaxHealth(enemyStrength*80);
			newUnit.setSpeed(60);
			weapon = new GenericPistol(10, 100);
			weapon.setRange(180000+3000*enemyStrength);
			newUnit.addWeapon(weapon);
			currentTargets.add(newUnit);
			main.units.add(newUnit);
			newUnit.spawn(p);
			break;
		default: //Default
			newUnit = new Seeker(CustomUtil.pointOffset(p, 50), AI);
			newUnit.setImageName("iconTank1.png");
			newUnit.setSpriteName("arrowSprite.png");
			newUnit.setWidth(35000);
			newUnit.setHeight(25000);
			newUnit.setMaxHealth(enemyStrength*100);
			newUnit.setSpeed(70+enemyStrength*3);
			weapon = new GenericPistol(50, 50);
			weapon.setRange(80000+1500*enemyStrength);
			newUnit.addWeapon(weapon);
			
			currentTargets.add(newUnit);
			main.units.add(newUnit);
			newUnit.spawn(p);
			break;
		}
		
		
		
	}
	
	private void phaseMessage(){
		MessageHandler.clearMessages();
		switch(phase){
		case 1:
			//MessageHandler.showMessage("You must survive the enemy attacks for as long as possible!", "iconShotgun.png");
			MessageHandler.addMessage("New group of waves, enemy strength is "+enemyStrength+"!", "iconShotgun.png");
			if(enemyStrength > 30){
				MessageHandler.addMessage("You. Will. DIE!", "iconDeath.png");
			} else if(enemyStrength > 12){
				MessageHandler.addMessage("So... You made it this far?", "iconNext.png");
			}
			break;
		default:
			break;
			
		}
	}
	public void setupAI(){
		PlayerData pd = new PlayerData('g');
		
		Unit u = new HeroUnit(0, 0, null);
		pd.addUnit(u);
		pd.selectNextUnit();
		u.actionMap.clear();
		u.actionMap.setWantedDepth(1);		
		u.actionMap.add(new FireShotgun());
		u.actionMap.add(new MoveHero());
		
		pd.setPlayerColor(Color.white);
		Point spawnPoint = new Point(100000, 100000);
		AI = new WorldAI(135*playerCounter+80, 100, playerCounter, pd.getKey(), spawnPoint, main);
		AI.setPlayerData(pd);
		AI.team=2;
		/*AI.toMainSpinner();
		AI.spawnFirstUnit();
		main.players.add(AI);
		*/
	}

}
